/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.anhndt.audiobook.ui;

import com.anhndt.audiobook.business.MediaPlayerControl;
import com.anhndt.audiobook.business.Resource;
import com.anhndt.audiobook.entity.ItemEntity;
import com.anhndt.audiobook.entity.ItemPartEntity;
import com.anhndt.audiobook.iface.IMediaListener;
import com.anhndt.audiobook.iface.ProcessListener;
import com.anhndt.audiobook.parser.ItemParser;
import com.anhndt.audiobook.utils.DialogUtil;
import com.anhndt.audiobook.utils.StringUtil;
import com.anhndt.audiobook.utils.Util;
import com.sun.lwuit.Button;
import com.sun.lwuit.Command;
import com.sun.lwuit.Component;
import com.sun.lwuit.Container;
import com.sun.lwuit.Display;
import com.sun.lwuit.Graphics;
import com.sun.lwuit.Image;
import com.sun.lwuit.Label;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
import com.sun.lwuit.events.FocusListener;
import com.sun.lwuit.layouts.BorderLayout;
import com.sun.lwuit.layouts.BoxLayout;
import com.sun.lwuit.layouts.GridLayout;
import com.sun.lwuit.plaf.UIManager;
import java.util.Vector;

/**
 *
 * @author Suns
 */
public class MediaPlayerForm extends BaseForm implements IMediaListener, ActionListener {

    private static final int PADDING = 8;
    private ProgressBar progress;
    private Image iconPlayNonSelect, iconPauseNonSelect, iconPlaySelected, iconPauseSelected;
    private Button btnRepeat, btnNext, btnPrev, btnFavorite, btnPlayOrPause, btnIncrementVolume, btnDecrementVolume;
    private Label lblCurTime, lblEndTime, lblNameArticle;
    private Button btnThumb;
    private Volume volume;
    private RateControl rate;
    private boolean isStartDownload, isDownloading;
    private static MediaPlayerControl control;
    private ItemEntity article;
    private static String articlePartID;        //cache is articlePartID playing
    boolean verticalScreen, muted;
    long startTicker;

    public static void releaseMediaControl() {
        System.out.println("[MediaPlayerForm] releaseMediaControl");
        if (control != null) {
            control.release();
            control = null;
        }
    }

    public static MediaPlayerControl getMediaControl() {
        return control;
    }

    public MediaPlayerForm(String title, BaseForm previous, ItemEntity article, int indexPlaying) {
        super(null, previous, null);

        try {
            this.article = article;
            Vector articleParts = article.getItemChildrends("" + ItemEntity.TYPE_ARTICLE_PART);
            String newArticleID = ((ItemEntity) articleParts.elementAt(indexPlaying)).id;
            if (control == null || StringUtil.isNullOrEmpty(articlePartID) || !newArticleID.equals(articlePartID)) {
                articlePartID = newArticleID;
                //release media control before create instance
                releaseMediaControl();
                control = new MediaPlayerControl(this, articleParts, indexPlaying);
            } else {
//            control.startDisplayTimer();
                control.setMediaPlayerListener(this);
            }
        } catch (Exception e) {
            backScreen();
        }
    }

//    protected void backScreen() {
//        if(control != null)
//            control.stopDisplayTimer();
//        super.backScreen();
//    }
    void setIconButton(Button btn, Image icon, Image iconSelected) {
        btn.setIcon(icon);
        btn.setPressedIcon(iconSelected);
        btn.setRolloverIcon(iconSelected);
    }

    void setIconPlayOrPause(boolean playing) {
        if (playing) {
            setIconButton(btnPlayOrPause, iconPauseNonSelect, iconPauseSelected);
        } else {
            setIconButton(btnPlayOrPause, iconPlayNonSelect, iconPlaySelected);
        }
    }

    void updateAllStatus() {
        ItemPartEntity playing = control != null ? control.getItemPlaying() : null;
        if (playing != null) {
            updateText();
            updateProgress(control.getTicking() * 1000 / playing.getDuration());
            updateTime();
            if (control.isPlaying() || control.isDownloading()) {
                setIconPlayOrPause(true);
            } else {
                setIconPlayOrPause(false);
            }
            if (control.isPaused() || control.isDownloading() || control.isPlaying()) {
                isStartDownload = true;
            } else {
                isDownloading = isStartDownload = false;
            }
        }
    }

    public void updateText() {
        ItemPartEntity playing = control.getItemPlaying();
        lblNameArticle.setShiftText(0);
        startTicker = System.currentTimeMillis();
        lblNameArticle.setText(playing.name + " - " + article.name);
        lblEndTime.setText(MediaPlayerControl.formatTime(playing.getDuration()));
    }

    private Button createButtonMedia(Image iconDefault, Image iconRollover, String selectedCommandText) {
        return createButtonMedia("ButtonMedia", iconDefault, iconRollover, selectedCommandText);
    }

    private Button createButtonMedia(String uiid, Image iconDefault, Image iconRollover, String selectedCommandText) {
        Button btn = new Button(iconDefault);
        btn.setUIID(uiid);
        btn.setAlignment(Button.CENTER);
        btn.setRolloverIcon(iconRollover);
        btn.setPressedIcon(iconRollover);
        btn.setSelectCommandText(selectedCommandText);
        btn.addActionListener(this);
        return btn;
    }

    String getNameArticlePartPlaying() {
        if (control != null && control.getItemPlaying() != null) {
            return ((ItemEntity) control.getItemPlaying()).name;
        }
        return "";
    }

    void startTicker() {
        if (lblNameArticle.shouldTickerStart()) {
            if (!lblNameArticle.isTickerRunning()) {
                startTicker = System.currentTimeMillis();
                lblNameArticle.startTicker(UIManager.getInstance().getLookAndFeel().getTickerSpeed(), true);
            }
        } else if (lblNameArticle.isTickerRunning()) {
            lblNameArticle.stopTicker();
        }
    }

    private void initComp() {
        //create component
        volume = new Volume();
        volume.setVolume(MediaPlayerControl.getVolume() / 10);
        volume.getUnselectedStyle().setMargin(Component.TOP, 5);
        volume.getSelectedStyle().setMargin(Component.TOP, 5);
        rate = new RateControl();
        if (Display.getInstance().isTouchScreenDevice()) {
            rate.setFocusable(true);
            rate.addFocusListener(new FocusListener() {

                public void focusGained(Component cmp) {
                }

                public void focusLost(Component cmp) {
                    //rating
                    if (rate.getFocusRate() != rate.getRate()) {
                        rate.callServiceRate(article.id);
                    }
                }
            });
        } else {
            rate.setFocusable(false);
        }
        progress = new ProgressBar();
        btnThumb = new Button(Util.getImageAsResource("logo"));
        btnThumb.setUIID("MediaThumb");
        btnThumb.setAlignment(Label.CENTER);
        btnThumb.setVerticalAlignment(Label.CENTER);
        btnThumb.addActionListener(this);

        lblNameArticle = new Label(control.getItemPlaying().name + " - " + article.name) {

            public boolean animate() {
                if (System.currentTimeMillis() - startTicker < 1500) {
                    return false;
                }
                return super.animate();
            }
        };
        lblNameArticle.setUIID("NameMediaPlaying");
        lblNameArticle.setAlignment(Label.CENTER);
        lblNameArticle.setTickerEnabled(true);
        lblNameArticle.setWidth(Display.getInstance().getDisplayWidth());
        startTicker();


        lblCurTime = new Label("00:00");
        lblEndTime = new Label("00:00");
        lblCurTime.setUIID("Timer");
        lblEndTime.setUIID("Timer");
//        lblCurTime.getStyle().setFont(Util.getSmallFont());
//        lblEndTime.getStyle().setFont(Util.getSmallFont());

        iconPlayNonSelect = Util.getImage("play");
        iconPlaySelected = Util.getImage("play_selected");
        iconPauseNonSelect = Util.getImage("pause");
        iconPauseSelected = Util.getImage("pause_selected");
        btnNext = createButtonMedia(Util.getImage("next"), Util.getImage("next_selected"), null);
        btnPrev = createButtonMedia(Util.getImage("prev"), Util.getImage("prev_selected"), null);
        btnFavorite = createButtonMedia(Util.getImage("favorite"), Util.getImage("favorite_selected"), Resource.BUTTON_FAVORITE);
        btnRepeat = createButtonMedia(Util.getImage("unrepeat"), Util.getImage("repeat_selected"), Resource.BUTTON_AUTO_NEXT);
        if (MediaPlayerControl.autonext) {
            btnRepeat.setIcon(Util.getImage("repeated"));
        }
        btnPlayOrPause = createButtonMedia(iconPlayNonSelect, iconPlaySelected, null);
        btnIncrementVolume = createButtonMedia("ButtonVolume", Util.getImage("volume_increase"), null, Resource.BUTTON_INCREMENT_VOLUME);
        btnDecrementVolume = createButtonMedia("ButtonVolume", Util.getImage("volume_decrease"), null, Resource.BUTTON_DECREMENT_VOLUME);

        volume.getUnselectedStyle().setMargin(Component.TOP, 5);
        volume.getSelectedStyle().setMargin(Component.TOP, 5);
    }

    /**
     * when user long press or long poiter press into Button Speaker
     */
    void mute() {
        muted = true;
        control.mute();
    }

    /**
     * when user long press or long poiter press into Button Speaker
     */
    void sound() {
        muted = false;
        control.sound();
    }

    protected void init() {
        Display.getInstance().setThirdSoftButton(true);
        super.init();
        form.removeComponent(form.getTitleArea());
        initComp();
        // Container Media Info : ProcessBar, text, rate
        Container conProcessBar = new Container(new BorderLayout());
        conProcessBar.addComponent(BorderLayout.WEST, lblCurTime);
        conProcessBar.addComponent(BorderLayout.CENTER, progress);
        conProcessBar.addComponent(BorderLayout.EAST, lblEndTime);

        Container conMediaInfo = new Container(new BoxLayout(BoxLayout.Y_AXIS));
        conMediaInfo.setUIID("MediaInfo");
        conMediaInfo.addComponent(lblNameArticle);
        conMediaInfo.addComponent(rate);
        conMediaInfo.addComponent(conProcessBar);
        //Container Media Control : VOLUME +HOME + PREV + STOP + NEXT + FAVORITE
        Container conVolume = new Container(new BorderLayout());
        conVolume.addComponent(BorderLayout.WEST, btnDecrementVolume);
        conVolume.addComponent(BorderLayout.CENTER, volume);
        conVolume.addComponent(BorderLayout.EAST, btnIncrementVolume);

        Container conButton = new Container(new GridLayout(1, 3));
        conButton.addComponent(btnPrev);
        conButton.addComponent(btnPlayOrPause);
        conButton.addComponent(btnNext);

        Container conButtonMediaControl = new Container(new BorderLayout());
        conButtonMediaControl.setUIID("ButtonMediaControl");
        conButtonMediaControl.addComponent(BorderLayout.WEST, btnRepeat);
        conButtonMediaControl.addComponent(BorderLayout.CENTER, conButton);
        conButtonMediaControl.addComponent(BorderLayout.EAST, btnFavorite);

        Container conMediaControl = new Container(new BorderLayout());
        conMediaControl.setUIID("MediaControl");
        conMediaControl.addComponent(BorderLayout.NORTH, conVolume);
        conMediaControl.addComponent(BorderLayout.SOUTH, conButtonMediaControl);

        //add all component into form
        body.addComponent(BorderLayout.NORTH, conMediaInfo);
        body.addComponent(BorderLayout.CENTER, btnThumb);
        body.addComponent(BorderLayout.SOUTH, conMediaControl);
        form.setFocused(btnPlayOrPause);
        form.addCommand(new Command(Resource.CMD_DOWNLOAD) {

            public void actionPerformed(ActionEvent evt) {
                if (control != null) {
                    ArticlePartForm.download(control.getItemPlaying());
                }
            }
        });
        updateAllStatus();
    }

    private void fireClick() {
        try {
            if (!isStartDownload) {
                start();
            } else if (isPlaying()) {
                pause();
            } else if (isDownloading) {
                reset();
            } else {
                //if it is paused
                resume();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void next() {
        reset();
        control.next();
    }

    private void prev() {
        reset();
        control.prev();
    }

    private void reset() {
        System.out.println("[MediaPlayerForm] reset");
        if (form == null) {
            return;
        }
        if (control != null) {
            control.stopLoadBlockAudio();
        }
        isStartDownload = false;
        downloading(false);
        progress.release();
        setIconPlayOrPause(false);
        lblCurTime.setText("00:00");
    }

    private void pause() {
        System.out.println("[MediaPlayerForm] pause");
        if (control.pause()) {
            setIconPlayOrPause(false);
        }
    }

    private void resume() {
        System.out.println("[MediaPlayerForm] resume");
        if (control.resume()) {
            setIconPlayOrPause(true);
        }
    }

    private boolean isPlaying() {
        return (control != null && control.isPlaying());
    }

    private void start() {
        isStartDownload = true;
        downloading(true);
        //        setIconPlayOrPause(true);
        control.start();

    }

    public void updateTime() {
//        System.out.println("MediaPlayerForm : updatTime");
        lblCurTime.setText(control.getMediaTimeStr());
    }

    public void updateVolume(int volume) {
        if (this.volume != null) {
            this.volume.setVolume(volume);
        }
    }

    public void updateStatus() {
//        System.out.println("update Name");
        updateAllStatus();
//        updateText();
    }

    public void updateProgress(float p) {
//        System.out.println("MediaPlayerForm : updateProcess");
        if (progress != null) {
            progress.updatePercentProgress(p);
        }
    }

    public void updateSecondaryProcess(float secondaryProgress) {
        if (progress != null) {
            progress.updatePercentSecondary(secondaryProgress);
        }
    }

    public void endOfSong() {
        System.out.println("endOfSong");
        reset();
        setIconPlayOrPause(false);
        control.release();
    }

    public void downloading(boolean isDownloading) {
        System.out.println("*********************** DOWNLOADING " + isDownloading + " *******************");
        if (form == null || this.isDownloading == isDownloading) {
            return;
        }
        this.isDownloading = isDownloading;
//        if (isDownloading) {
//            lblNameArticle.setText(Resource.LOADING_MESSAGE);
//        } else {
//            lblNameArticle.setText(control.getItemPlaying().name + " - " + article.name);
//        }
        if (isDownloading) {
            Indicator.show("Đang tải audio", null);
        } else {
            Indicator.hide();
            Util.gc();
        }
    }

    public void actionPerformed(ActionEvent evt) {
        Object source = evt.getSource();
        if (source instanceof Button) {
            actionMediaControl((Button) source);
        }
    }

    private void actionMediaControl(Button btn) {
        System.out.println("btn :" + btn);
        if (btn == btnNext) {
            next();
        } else if (btn == btnPrev) {
            prev();
        } else if (btn == btnPlayOrPause) {
            fireClick();
        } else if (btn == btnFavorite) {
            if (article != null) {
                new Thread() {

                    public void run() {
                        ItemParser favoriteAdd = new ItemParser(article.id, ItemEntity.TYPE_FAVORITE_ADD);
                        favoriteAdd.callservice();
                        DialogUtil.showInfoDialog(Resource.TXT_ADD_FAVORITE_SUCCESSFUL);
                    }
                }.run();

                //TODO treatment if faile in here
            }
        } else if (btn == btnRepeat) {
            MediaPlayerControl.autonext = !MediaPlayerControl.autonext;
            if (MediaPlayerControl.autonext) {
                setIconButton(btnRepeat, Util.getImage("repeated"), Util.getImage("repeat_selected"));
            } else {
                setIconButton(btnRepeat, Util.getImage("unrepeat"), Util.getImage("unrepeat"));
            }
        } else if (btn == btnDecrementVolume) {
            MediaPlayerControl.decrementVolume();
        } else if (btn == btnIncrementVolume) {
            MediaPlayerControl.incrementVolume();
        }
    }

    public void exception(int exception) {
        if (exception == IO_EXCEPTION || exception == MEDIA_EXCEPTION) {
            DialogUtil.showWarningDialog(Resource.TXT_WARRING_CAN_NOT_PLAY_MEDIA);
            reset();
        }
    }

    public void loadThumb() {
        ItemEntity itemThumbnail = new ItemEntity(article.id, null, null, ItemEntity.TYPE_ARTICLE);
        btnThumb.setSelectCommandText("");

//        final String u = (advImage != null) ? advImage.getThumbUrl() : article.getThumbUrl();
//        ItemEntity thumb = new ItemEntity(u, u, u, tag) {
//
//            public String getThumbUrl() {
//                return u;
//            }
//
//        };
        int thickness = btnThumb.getSelectedStyle().getBorder().getThickness();
        int width = btnThumb.getWidth() - 2 * thickness;
        int height = btnThumb.getHeight() - 2 * thickness;
        Vector vt = new Vector();
        vt.addElement(itemThumbnail);
        ProcessListener callbackLoadedImage = new ProcessListener() {

            public void onSuccess(Object result, int index) {
                Image img = (Image) result;
                setIconButton(btnThumb, img, img);
                btnThumb.setIcon(img);
                btnPlayOrPause.setSelectCommandText("");
                form.repaint();
            }

            public void onError(String status, int index) {
            }
        };
        loadThumb(vt, height, width, getPrefixLoadThumb(), false, callbackLoadedImage);
    }

    public String getThumbUrlSong(String url) {
        return Util.getImageUrl(url, btnThumb.getWidth(), btnThumb.getHeight(), false);
    }

    class ProgressBar extends Component {

        private final int HEIGHT_PROGRESSBAR = 4;
        private float percentSecondary;
        private float percentProgress;
        private Image icon = null;
        private int iconWidth;

        /**
         * The default constructor uses internal rendering to draw the progress
         */
        public ProgressBar() {
            setFocusable(false);
            if (icon == null) {
                icon = Util.getImage("point");
            }
            iconWidth = icon.getWidth();
            setPreferredH(Math.max(HEIGHT_PROGRESSBAR, icon.getHeight()));
            setBorderPainted(false);

        }

        public String getUIID() {
            return "Progress";
        }

        public void release() {
            this.percentProgress = 0;
            this.percentSecondary = 0;
            repaint();
        }

        public void updatePercentProgress(float percentProgress) {
            this.percentProgress = percentProgress;
            repaint();
        }

        public void updatePercentSecondary(float percentSecondary) {
            this.percentSecondary = percentSecondary;
            repaint();
        }

        protected void paintBackground(Graphics g) {
        }

        /**
         * Paint the progress indicator
         */
        public void paint(Graphics g) {
            //        super.paint(g);
            int x = getX() + 1;
            int y = getY();
            int yCenter = y + (getPreferredH() - HEIGHT_PROGRESSBAR) / 2;
            int width = getWidth() - iconWidth - 2;
            int playingProgressWidth = (int) (percentProgress * width) / 1000;
            int loadingProgressWidth = (int) (percentSecondary * width) / 1000;
            if (playingProgressWidth > width) {
                playingProgressWidth = width;
            }
            if (loadingProgressWidth > width) {
                loadingProgressWidth = width;
            }
            //draw progressbar
            g.setColor(getSelectedStyle().getBgColor());
            g.fillRoundRect(x, yCenter, getWidth() - 2, HEIGHT_PROGRESSBAR, 5, 5);
            //draw point
            g.drawImage(icon, x + playingProgressWidth, y);
            //draw secondary progress
            //        g.setColor(0x111111);
            //        g.fillRoundRect(x, yCenter, playingProgressWidth, HEIGHT_PROGRESSBAR, 5, 5);
        }

    }

    class Volume extends Component {

        final int ABSOLUTE_HEIGHT = 4;
        private int volume;

        public Volume() {
            setEnabled(false);
        }

        public String getUIID() {
            return "Volume";
        }

        public void setVolume(int volume) {
            if (volume >= 0 && volume <= 10) {
                this.volume = volume;
                repaint();
            }
        }

        public int getVolume() {
            return volume;
        }

        protected void paintBackground(Graphics g) {
        }

        public void paint(Graphics g) {
            int w = getWidth();
            int h = ABSOLUTE_HEIGHT;
            int x = getX();
            int y = getY() + (getHeight() - ABSOLUTE_HEIGHT) / 2 - 2;
            g.clipRect(x, y, w, h);
            //draw full
            g.setColor(getUnselectedStyle().getBgColor());
            g.fillRoundRect(x, y, w, h, 5, 5);
            //draw volume
            g.setColor(getSelectedStyle().getBgColor());
            g.fillRoundRect(x, y, w * volume / 10, h, 5, 5);
        }
    }
}
